import java.awt.*;
import javax.swing.*;
import java.util.*;
public class ProducerAndConsumer extends JFrame
{
	Container c = null;
	JPanel pn = new JPanel();
	
	public ProducerAndConsumer()
	{
		c = getContentPane();
		pn.setBackground(Color.black);
		pn.setForeground(Color.black);
		c.add(pn,BorderLayout.CENTER);
		setSize(650,400);
		setVisible(true);
	}
	public static void main(String args[])
	{
		ProducerAndConsumer app = new ProducerAndConsumer();
		PCMonitor mtr = new PCMonitor();
		for(int i=0;i<=3;i++)
		(new Thread(new Producer(i,mtr,app.pn))).start();
	}
}

class PCMonitor
{
	public static int nextItem = 1;
	int count,in,out,item[];
	
	public PCMonitor()
	{
		count = in =out =0;
		item = new int[10];
	}


synchronized public void put(int iLabel)
{
	try
	{
		while(count>=item.length)wait();
		item[in]=iLabel;
		in = (in+1)%item.length;
		count++;
		notify();
	}
	catch (InterruptedException e){}
}

synchronized public int get()
{
	try
	{
		while(count==0)wait();
		int itm = item[out];
		out = (out+1)%item.length;
		count--;
		return itm;
	}
	catch(InterruptedException e){}
	return -1;
}

synchronized public int getNo()
{
	int n = nextItem ++;
	return n;
}
}

class Producer implements Runnable
{
	public static Random rdm = new Random();
	int ID;
	PCMonitor mtr = null;
	JPanel pn = null;
	Graphics g = null;
	int lastItem;
	public Producer(int id,PCMonitor m,JPanel p)
	{
		ID = id;
		mtr = m;
		pn = p;
		g = pn.getGraphics();
	}
	public void run()
	{
		while(true)
		{	
			simulate("working",4,6);
			simulate("putting",1,2);
			lastItem = mtr.getNo();
			mtr.put(lastItem);
			draw(String.format("producer %d has produced item %d",ID,lastItem));
			simulate("relaxing",2,3);
		}
	}
	void draw(String s)
	{
		int x=20,y = ID*30;
		g.setColor(pn.getBackground());
		g.fillRect(x,y-25,300,28);
		g.setColor(Color.white);
		g.drawString("Producer "+ID+"("+lastItem+"):"+s,x,y);
	}
	void simulate(String s,int lb,int ub)
	{
		draw(s);
		try
		{	
			Thread.sleep(rdm.nextInt(ub*1000-lb*1000+1)+lb*1000);
		}
		catch(InterruptedException e){}
	}
class Consumer implements Runnable
{	 
	public void run(){}
}
}